﻿///////////////////////////////// Hamzeh amri sarlak /////////////////////////////

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using QueuingSimulation;

namespace Simulation1QueueAndMultiServer
{
    public partial class Main : Form
    {
        public List<Server> Servers = new List<Server>();
        public Main()
        {
            InitializeComponent();
        }
        private Simulation _simulation;
        private void buttonSimulation_Click(object sender, EventArgs e)
        {
            var action = new MethodInvoker(delegate
            {
                txtLogs.Text = string.Empty;
                var isTimeBase = rdoTimeBase.Checked;
                var simType = isTimeBase ? SimulationType.TimeBase : SimulationType.ClientCountBase;
                _simulation = new Simulation(simType, (double)txtTimerSpeed.Value)
                {
                    Servers = GetServers(),
                    ClientEnterRangeTime = new ClientEnterRangeTime
                    {
                        From = (int)txtEnterTimeFrom.Value,
                        To = (int)txtEnterTimeTo.Value
                    },
                    TotalWork = (int)txtTotalBankerWorkTime.Value
                };
                _simulation.SimulationEnded += SimulationOnSimulationEnded;
                _simulation.ClientStateChange += SimulationOnClientStateChange;
                _simulation.Start();
            });
            BeginInvoke(action);
        }

        private void SimulationOnClientStateChange(object sender, ClientStateChangeEventArgs e)
        {
            var action = new MethodInvoker(delegate
            {
                txtLogs.AppendText("Client ID: " + e.Client.ID + ", Time: " + e.Time + " State: " + e.ClientState + Environment.NewLine);
                if (e.ClientState == ClientState.ServiceStart)
                {
                    txtLogs.AppendText("DedicatedServer: " + e.Client.DedicatedServer + Environment.NewLine);
                }
                txtLogs.AppendText(Environment.NewLine);
            });
            BeginInvoke(action);
        }

        private void SimulationOnSimulationEnded(object sender, EventArgs eventArgs)
        {
            var action = new MethodInvoker(delegate
            {
                dataGridViewCustomer.DataSource = _simulation.Clients;
                DeteminateGridRowBgColor();
                PrintQueries();
            });
            BeginInvoke(action);

        }

        public void PrintQueries()
        {
            txtQueries.Text += Environment.NewLine + "---------------------------------Results--------------------------------" + Environment.NewLine;
            txtQueries.Text += "Customer wait in queue avarage : ";
            txtQueries.Text += Math.Round(_simulation.Clients.Sum(c => c.WaitInQueueTime) / (double)_simulation.Clients.Count, 2).ToString();
            txtQueries.Text += Environment.NewLine;
            txtQueries.Text += Environment.NewLine;

            txtQueries.Text += "Customer total waiting time avarage : ";
            txtQueries.Text += Math.Round(_simulation.Clients.Sum(c => c.TotalWaitingTime) / (double)_simulation.Clients.Count, 2).ToString();
            txtQueries.Text += Environment.NewLine;
            txtQueries.Text += Environment.NewLine;

            txtQueries.Text += "Maximum of customer queue length : ";
            txtQueries.Text += _simulation.GetMaxQueueSize().ToString();
            txtQueries.Text += Environment.NewLine;
            txtQueries.Text += Environment.NewLine;


            txtQueries.Text += "Work time : ";
            txtQueries.Text += _simulation.TimerValue.ToString();
            txtQueries.Text += Environment.NewLine;
            txtQueries.Text += Environment.NewLine;


            foreach (var server in _simulation.Servers)
            {
                txtQueries.Text += "-------------------" + server.Name + " details-------------------";
                txtQueries.Text += Environment.NewLine;
                txtQueries.Text += "Total busy time : ";
                txtQueries.Text += server.GetTotalBusyTime().ToString();
                txtQueries.Text += Environment.NewLine;
                txtQueries.Text += Environment.NewLine;
                txtQueries.Text += "Total free time : ";
                txtQueries.Text += server.GetTotalFreeTime().ToString();
                txtQueries.Text += Environment.NewLine;
                txtQueries.Text += Environment.NewLine;
                txtQueries.Text += "Number of clients served : ";
                txtQueries.Text += _simulation.GetTotalServerClients(server).ToString();
                txtQueries.Text += Environment.NewLine;
                txtQueries.Text += Environment.NewLine;
            }
        }
        public void DeteminateGridRowBgColor()
        {
            for (int i = 0; i < dataGridViewCustomer.Rows.Count; i++)
                if (i % 2 == 0)
                    dataGridViewCustomer.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
        }

        private void tabReport_SelectedIndexChanged(object sender, EventArgs e)
        {
            DeteminateGridRowBgColor();
        }

        private void Main_Load(object sender, EventArgs e)
        {

        }

        private void btnAddServer_Click(object sender, EventArgs e)
        {
            Servers.Add(new Server
            {
                Name = txtName.Text,
                Priority = (int)txtPriority.Value,
                MinServiceTime = (int)txtServiceTimeFrom.Value,
                MaxServiceTime = (int)txtServiceTimeTo.Value,
                ServerState = ServerState.Free
            });
            BindServersData();
        }

        public List<Server> GetServers()
        {
            var lstServers = Servers.Select(server => new Server
            {
                Name = server.Name,
                Priority = server.Priority,
                MinServiceTime = server.MinServiceTime,
                MaxServiceTime = server.MaxServiceTime,
                ServerState = ServerState.Free
            }).ToList();
            return lstServers;
        }

        public void BindServersData()
        {
            dataGridViewServers.ReadOnly = true;
            var sers = new List<Server>();
            sers.AddRange(Servers);
            dataGridViewServers.DataSource = sers;
            //dataGridViewServers.Columns["Timer"].Visible = false;
            dataGridViewServers.Columns["ServerState"].Visible = false;
            dataGridViewServers.Columns["Timer"].Visible = false;
            dataGridViewServers.Columns["TimerInterval"].Visible = false;
        }

    }
}


///////////////////////////////// Hamzeh amri sarlak /////////////////////////////